﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace QuickVal.Validators
{
    public class RequiredIfValidator : DataAnnotationsModelValidator<RequiredIfAttribute>
    {
        public RequiredIfValidator(ModelMetadata metadata, ControllerContext context, RequiredIfAttribute attribute) : base(metadata, context, attribute) { }

        public override IEnumerable<ModelValidationResult> Validate(object container)
        {
            // Get a reference to the property this validation depends upon
            var field = Metadata.ContainerType.GetProperty(Attribute.DependentProperty);
            
            // Allow override of error message from a remote field
            var errorField = Metadata.ContainerType.GetProperty(Attribute.ErrorProperty);
            var errorMessage = ErrorMessage;

            if (field != null)
            {
                // Override the error message with a remote field if there is a value
                if (errorField != null)
                    if (errorField.GetValue(container, null) != null)
                        errorMessage = string.IsNullOrWhiteSpace((string)errorField.GetValue(container, null)) ? ErrorMessage : (string)errorField.GetValue(container, null);

                // Get the value of the dependent property
                var value = field.GetValue(container, null);

                // Compare the value against the target value
                if ((value == null && Attribute.TargetValue == null) || (value != null && value.ToString().ToLowerInvariant().Equals(Attribute.TargetValue.ToString().ToLowerInvariant())))
                {
                    if (Metadata.Model != null)
                    {
                        // Get the value
                        var thisVal = (string)Metadata.Model;

                        if (string.IsNullOrWhiteSpace(thisVal))
                            // Validation failed - return an error
                            yield return new ModelValidationResult { Message = errorMessage };
                    }
                    else
                        // It's null - return an error
                        yield return new ModelValidationResult { Message = errorMessage };
                }
            }
        }
    }
}
